<template>
  <transition name="fade">
    <div v-if="visible" class="opening-alt">
      <canvas ref="canvasRef" class="webgl" />
      <div class="brand">SHU AI</div>
    </div>
  </transition>
</template>

<script setup lang="ts">
import { onMounted, onBeforeUnmount, ref } from 'vue'
import * as THREE from 'three'

const canvasRef = ref<HTMLCanvasElement | null>(null)
const visible = ref(false)
let renderer: THREE.WebGLRenderer | null = null
let scene: THREE.Scene | null = null
let camera: THREE.PerspectiveCamera | null = null
let animationId = 0
let points: THREE.Points | null = null

const dispose = () => {
  cancelAnimationFrame(animationId)
  renderer?.dispose()
  scene = null
  camera = null
  points = null
}

onMounted(() => {
  const canvas = canvasRef.value!
  scene = new THREE.Scene()
  scene.background = new THREE.Color(0x0f0f0f)
  camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 0.1, 100)
  camera.position.set(0, 0, 6)
  renderer = new THREE.WebGLRenderer({ canvas, antialias: true })
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
  renderer.setSize(window.innerWidth, window.innerHeight)

  const count = 1200
  const positions = new Float32Array(count * 3)
  for (let i = 0; i < count; i++) {
    positions[i * 3 + 0] = (Math.random() - 0.5) * 12
    positions[i * 3 + 1] = (Math.random() - 0.5) * 12
    positions[i * 3 + 2] = (Math.random() - 0.5) * 12
  }
  const geometry = new THREE.BufferGeometry()
  geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3))
  const material = new THREE.PointsMaterial({ size: 0.04, color: 0xffffff })
  points = new THREE.Points(geometry, material)
  scene.add(points)

  const onResize = () => {
    if (!renderer || !camera) return
    camera.aspect = window.innerWidth / window.innerHeight
    camera.updateProjectionMatrix()
    renderer.setSize(window.innerWidth, window.innerHeight)
  }
  window.addEventListener('resize', onResize)

  visible.value = true

  const clock = new THREE.Clock()
  const tick = () => {
    const t = clock.getElapsedTime()
    if (points) {
      points.rotation.x = t * 0.08
      points.rotation.y = t * 0.12
    }
    renderer?.render(scene!, camera!)
    animationId = requestAnimationFrame(tick)
  }
  tick()
})

onBeforeUnmount(() => dispose())
</script>

<style scoped>
.opening-alt {
  position: fixed;
  inset: 0;
  background: #0f0f0f;
  display: grid;
  place-items: center;
  z-index: 1999;
}

.webgl {
  width: 100%;
  height: 100%;
  display: block;
}
.brand {
  position: absolute;
  color: #fff;
  font-weight: 800;
  letter-spacing: 4px;
  font-size: 24px;
}

.fade-enter-active,
.fade-leave-active {
  transition:
    opacity 0.6s ease,
    transform 0.6s ease;
}
.fade-enter-from,
.fade-leave-to {
  opacity: 0;
  transform: scale(1.02);
}
</style>


